home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 282_01 / gears.c < prev    next >
Text File  |  1989-01-11  |  9KB  |  354 lines

  1. /*
  2. TITLE:        GEARS;
  3. DATE:        9/8/88;
  4. DESCRIPTION:    "Bicycle gear chart calculator.";
  5. VERSION:    1.00;
  6. KEYWORDS:    Bicycle, Gears;
  7. FILENAME:    GEARS.C;
  8. WARNINGS:    "Uses Aztec scr_ functions";
  9. SEE-ALSO:    GEARS.EXE, GEARS.DOC;
  10. SYSTEM:        MS-DOS;
  11. COMPILERS:    Aztec;
  12. AUTHORS:    Dan Schechter;
  13.  */
  14.  
  15. /* GEARS is a bicycle gear chart calculator.
  16. To port it to other systems/compilers, note the following:
  17. All the functions beginning scr_ are Aztec C IBM-specific functions.
  18. They require 100% PC-compatible computers. Their actions are the following:
  19.  
  20. scr_getc() causes program operation to halt until a key is pressed
  21. and then returns that key. It is not necessary to press ENTER as would
  22. be required in the case of getchar().
  23.  
  24. scr_clear() clears the screen and places the cursor at the upper left.
  25.  
  26. scr_curs(v,h) places the cursor at position v,h on the screen. Both
  27. vertical and horizontal positions are numbered from 0.
  28.  
  29. scr_eol() erases from the current cursor position to the end of the line and 
  30. scr_eos() erases from the current cursor position to the end of the screen. 
  31.  
  32. I presume that similar functions should be available (or easy to write)
  33. on any system and any compiler. Good luck!
  34.  */
  35.  
  36. #define VERSION "Version 1.00 9/8/88"
  37.  
  38. #define CHAINNUM 2        /* Default number of chain rings. */
  39. #define MAXCHAIN 3        /* Maximum number of chain rings. */
  40. #define FREENUM 6        /* Default number of freewheel sprockets. */
  41. #define MAXFREE 8        /* Maximum ditto. */
  42. #define CHAINCOL 0        /* Sxcreen column for chain cog numbers. */
  43. #define FREELINE 7        /* Screen line for freewheel cog numbers. */
  44. #define SLACKLINE 5        /* Screen line for slack. */
  45. #define SLACKCOL 25        /* Screen column for slack. */
  46. #define WHEEL 27        /* Default wheel size. */
  47. #define HSTEP 7            /* Horizontal screen spacing. */
  48. #define VSTEP 2            /* Vertical screen spacing. */
  49.  
  50. #define LEFT 203    /* char returned by scr_getc() on left arrow. */
  51. #define RIGHT 205    /* ditto for right arrow. */
  52. #define UP 200        /* ditto for up arrow. */
  53. #define DOWN 208    /* ditto for down arrow. */
  54.                 
  55.                 /* If your system does not have arrow
  56.                 keys you can replace the above 4 with
  57.                 whatever keyboard characters you like. */
  58.  
  59. #define BS '\b'
  60. #define TAB '\t'
  61. #define A_CHAR '>'        /* Character to indicate auto-advance. */
  62. #define XA_CHAR    '<'        /* Char to indicate no auto-advance. */
  63.  
  64. int chainnum=CHAINNUM,freenum=FREENUM,wheel=WHEEL;
  65. int autoadv=1;
  66.  
  67. /* The following uses IBM character graphics to draw a cat. 
  68. For non-IBM systems use this line instead:
  69. char *cat = "";
  70.  */
  71.  
  72. unsigned char cat[44] = {
  73.     0x20, 0x20, 0x20, 0x20, 0x2f, 0x5c, 0x5f, 0x2f, 0x5c, '\n',
  74.     0x20, 0x20, 0x20, 0x28, 0xfe, 0x20, 0xd2, 0x20, 0xfe, 0x29, '\n',
  75.     0xf0, 0xf0, 0xf0, 0xf0, 0x20, 0xc4, 0xca, 0xc4, 0x20, 0xf0, 
  76.           0xf0, 0xf0, 0xf0, '\n',
  77.     0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x22, 0x22, 0x00
  78. };
  79.  
  80. /* If your compiler complains about long strings, you may have to break
  81. up the following help message into two or three separate chunks. */
  82.  
  83. char *help_msg = 
  84. "\nUsage: GEARS [w<w>] [c<c>] [f<f>]\n"
  85. "<w> is wheel size,\n"
  86. "<c> is number of chain rings,\n"
  87. "<f> is number of freewheel gears.\n\n"
  88. "You must list freewheel sprocket numbers across the top, \n"
  89. "smallest on the left and largest on the right,\n"
  90. "and chain ring sprocket numbers along the side, largest on top.\n"
  91. "Crossover gears are marked with an asterisk in the chart\n"
  92. "and are deleted from the numerical-order list below the chart.\n\n"
  93. "Use ENTER or BACKSPACE to move the cursor to the next or previous gear.\n"
  94. "Use left-arrow and right-arrow to move cursor between digits of a gear.\n"
  95. "Use TAB to toggle auto-advance.\n"
  96. "Press X to exit.\n"
  97. "Use PrtScr to print screen display.\n"
  98. ;
  99.  
  100. int main(n,arg)
  101. int n;
  102. char **arg;
  103. {
  104.     int v,h,index,position;    /* index is present cog, position is 0 or 1 */
  105.     char datastring[(MAXCHAIN+MAXFREE)*2];
  106.     int c;
  107.     void help(),display();
  108.     
  109.     while (n>1){
  110.         n--;
  111.         switch(tlr(arg[n][0])){
  112.             case 'w':
  113.                 wheel=atoi(arg[n]+1);
  114.                 break;
  115.             case 'c':
  116.                 chainnum=atoi(arg[n]+1);
  117.                 break;
  118.             case 'f':
  119.                 freenum=atoi(arg[n]+1);
  120.                 break;
  121.             case '?':
  122.                 printf(help_msg);
  123.                 exit(0);
  124.             default:
  125.                 printf("Unrecognized parameter: %s",arg[n]);
  126.                 exit(1);
  127.         }
  128.     }
  129.     if ((wheel<=0)||(wheel>50)){
  130.         printf ("Wheel size out of bounds.");
  131.         exit(1);
  132.     }
  133.     if ((chainnum<=0)||(chainnum>MAXCHAIN)){
  134.         printf("Number of chain rings out of bounds.");
  135.         exit(1);
  136.     }
  137.     if ((freenum<=0)||(freenum>MAXFREE)){
  138.         printf("Number of freewheel gears out of bounds.");
  139.         exit(1);
  140.     }
  141.     
  142.     scr_clear();
  143.     
  144.     printf("%s\nKittensoft bicycle gear chart calculator. %s\nWheel is %d inches.",cat,VERSION,wheel);
  145.     
  146.     for(h=0;h<(chainnum+freenum)<<1;h++) datastring[h]=' ';
  147.     display(datastring);
  148.     scr_curs(FREELINE,CHAINCOL+HSTEP);
  149.     for(position=index=0;;){
  150.         switch(tlr(c=scr_getc())){
  151.             case 'x':
  152.             case 3:
  153.                 scr_curs(FREELINE+VSTEP*chainnum+7,0);
  154.                 exit(0);
  155.             case DOWN:
  156.             case '\r':
  157.                 position=0;
  158.                 index++;
  159.                 if (index==chainnum+freenum) index=0;
  160.                 break;
  161.             case TAB:
  162.                 autoadv ^= 1;
  163.                 scr_curs(FREELINE,0);
  164.                 putchar( autoadv ? A_CHAR : XA_CHAR );
  165.                 break;
  166.             case UP:
  167.             case BS:
  168.                 position=0;
  169.                 index--;
  170.                 if (index==-1) index=chainnum+freenum-1;
  171.                 break;
  172.             case LEFT:
  173.                 if (position) position=0;
  174.                 break;
  175.             case RIGHT:
  176.                 if (!position) position=1;
  177.                 break;
  178.             case '?':
  179.             case '/':
  180.                 help(datastring);
  181.                 break;
  182.             default:
  183.                 if (((c<'0')||(c>'9'))&&(c!=' ')) break;
  184.                 datastring[(index<<1) + position]=c;
  185.                 if (!position) position=1;
  186.                 else {
  187.                     position=0;
  188.                     if (autoadv){
  189.                         index++;
  190.                         if (index==chainnum+freenum) index=0; 
  191.                     }
  192.                 }
  193.                 display(datastring);
  194.                 break;
  195.         }
  196.         if (index<freenum){
  197.             v=FREELINE;
  198.             h= CHAINCOL + HSTEP + index*HSTEP + position;
  199.         }
  200.         else {
  201.             h=CHAINCOL+position;
  202.             v= FREELINE + VSTEP + VSTEP*(index-freenum);
  203.         }
  204.         scr_curs(v,h);
  205.     }
  206. }
  207. int cmp(a,b)
  208. double *a,*b;
  209. {
  210.     if ((*a)==(*b)) return 0;
  211.     return( ((*a)<(*b))? 1:-1 );
  212. }
  213. int getsprocket(s,i)
  214. int i;
  215. char *s;
  216. {
  217.     int n;
  218.  
  219.     i<<=1;
  220.     if ((s[i]==' ')&&(s[i+1]==' ')) return(-1);
  221.     
  222.     n= s[i++]-48;
  223.     if (n<0) n=0;
  224.     
  225.     if (s[i]==' ') return n;
  226.     n*=10;
  227.     n+= s[i]-48;
  228.     
  229.     return n;
  230. }
  231. double calculate(c,f)
  232. int c,f;
  233. {
  234.  
  235.     return (((double)c/(double)f)*(double)wheel);
  236. }
  237. void help(s)
  238. char *s;
  239. {
  240.     int h,v;
  241.     
  242.     scr_clear();
  243.     printf(help_msg);
  244.     printf("\nPRESS ANY KEY TO RETURN TO THE PROGRAM. ");
  245.     scr_getc();
  246.     scr_clear();
  247.     printf("%s\nKittensoft bicycle gear chart calculator. %s\nWheel is %d inches.",cat,VERSION,wheel);
  248.     display(s);
  249. }
  250. int tlr(c)
  251. int c;
  252. {
  253.     if ((c>='A')&&(c<='Z')) c|=32;
  254.     return c;
  255. }
  256.  
  257. void display(s)
  258. char *s;
  259. {
  260.     int i,j,v,h,count,q;
  261.     int chain,free,cmp();
  262.     int chains[MAXCHAIN],frees[MAXFREE];
  263.     double t,tt,g[MAXCHAIN*MAXFREE],calculate(int,int);
  264.     
  265.     for(i=j=0,v=FREELINE;i<freenum;i++,j+=2){
  266.         h=CHAINCOL + HSTEP + i*HSTEP;
  267.         scr_curs(v,h);
  268.         if ((s[j]==' ')&&(s[j+1]==' ')) printf("? ");
  269.         else {
  270.             putchar(s[j]);
  271.             putchar(s[j+1]);
  272.         }
  273.     }
  274.     for(i=0,h=CHAINCOL;i<chainnum;i++,j+=2){
  275.         v=FREELINE + VSTEP + i*VSTEP;
  276.         scr_curs(v,h);
  277.         if ((s[j]==' ')&&(s[j+1]==' ')) printf("? ");
  278.         else {
  279.             putchar(s[j]);
  280.             putchar(s[j+1]);
  281.         }
  282.     }
  283.     for(i=count=0;i<freenum;i++){
  284.         h= CHAINCOL + HSTEP + i*HSTEP;
  285.         free=frees[i]= getsprocket(s,i);
  286.         for(j=q=0;j<chainnum;j++,q=0){
  287.             v= FREELINE + VSTEP + j*VSTEP;
  288.             scr_curs(v,h);
  289.             printf("       \b\b\b\b\b\b\b");
  290.             chain=chains[j]=getsprocket(s,freenum+j);
  291.             if (((i==freenum-1)&&(!j))||((!i)&&(j==chainnum-1))){
  292.                 putchar('*');
  293.                 q=1;
  294.             }
  295.             if ((chain<=0)||(free<=0)) putchar('?');
  296.             else {
  297.                 t=calculate(chain,free);
  298.                 if (!q) g[count++]=t;
  299.                 printf("%-5.1f",t);
  300.             }
  301.         }
  302.     }
  303.     h=CHAINCOL + HSTEP + 4 + freenum*HSTEP;
  304.     for (i=1;i<chainnum;i++){
  305.         v= FREELINE + i*VSTEP +1;
  306.         scr_curs(v,h);
  307.         t=getsprocket(s,freenum+i);
  308.         tt=getsprocket(s,freenum+i-1);
  309.         if ((tt>0.0)&&(t>0.0))
  310.             printf("%.0f%%", ((tt-t)/tt)*100.0 );
  311.         else putchar('?');
  312.         scr_eol();
  313.     }
  314.     v=FREELINE + VSTEP +ch